unit LSShare;

interface
uses
  Windows, Messages, Classes, SysUtils, SyncObjs, MudUtil, IniFiles, Grobal2, sdk;
type
  TGateNet = record
    sIPaddr: string;
    nPort: Integer;
    boEnable: Boolean;
  end;
  TGateRoute = record
    sServerName: string;
    sTitle: string;
    sRemoteAddr: string;
    sPublicAddr: string;
    nSelIdx: Integer;
    Gate: array[0..9] of TGateNet;
  end;
  TConfig = packed record
    IniConf: TIniFile;
    boRemoteClose: Boolean;
    sDBServer: string[30];
    nDBSPort: Integer;
    sFeeServer: string[30];
    nFeePort: Integer;
    sLogServer: string[30];
    nLogPort: Integer;
    sGateAddr: string[30];
    nGatePort: Integer;
    sServerAddr: string[30];
    nServerPort: Integer;
    sMonAddr: string[30];
    nMonPort: Integer;
    sGateIPaddr: string[30];
    sIdDir: string[50];
    sWebLogDir: string[50];
    sFeedIDList: string[50];
    sFeedIPList: string[50];
    sCountLogDir: string[50];
    sChrLogDir: string[50];
    boTestServer: Boolean;
    boEnableMakingID: Boolean;
    boGetbackPassword: Boolean;
    boDynamicIPMode: Boolean;
    boAutoClear: Boolean;
    dwAutoClearTime: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    nReadyServers: Integer;
    boAllowChangePassword: Boolean;

    GateCriticalSection: TRTLCriticalSection;
    GateList: TList;
    SessionList: TGList;
    ServerNameList: TStringList;
    AccountCostList: TQuickList;
    IPaddrCostList: TQuickList;
    boShowDetailMsg: Boolean;
    dwProcessGateTick: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    dwProcessGateTime: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    nRouteCount: Integer;
    GateRoute: array[0..59] of TGateRoute;
    dwAddNewUserTick: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    dwChgPassWordTick: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    dwUpdateUserInfoTick: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    GetBackPasswordTick: {$IFDEF TICK64}NativeUInt{$ELSE}LongWord{$ENDIF};
    nLockIdTick: {$IFDEF TICK64}NativeUInt{$ELSE}Integer{$ENDIF};
    CLPort: Integer;
    CLPwd: Integer;
    CLOpen: Boolean;
  end;
  pTConfig = ^TConfig;

function CheckAccountName(sName: string): Boolean;
function GetSessionID(): Integer;
procedure SaveGateConfig(Config: pTConfig);
function GetGatePublicAddr(Config: pTConfig; sGateIP: string): string;
function GenSpaceString(sStr: string; nSpaceCOunt: Integer): string;
procedure MainOutMessage(sMsg: string);
procedure SendGameCenterMsg(wIdent: Word; sSendMsg: string);

var

  g_Config                  : TConfig = (
    boRemoteClose: False;
    sDBServer: '127.0.0.1';
    nDBSPort: 16300;
    sFeeServer: '127.0.0.1';
    nFeePort: 16301;
    sLogServer: '127.0.0.1';
    nLogPort: 16301;
    sGateAddr: '0.0.0.0';
    nGatePort: 5500;
    sServerAddr: '0.0.0.0';
    nServerPort: 5600;
    sMonAddr: '0.0.0.0';
    nMonPort: 3000;
    sGateIPaddr: '0.0.0.0';

    sIdDir: '.\DB\';
    sWebLogDir: '.\Share\';
    sFeedIDList: '.\FeedIDList.txt';
    sFeedIPList: '.\FeedIPList.txt';
    sCountLogDir: '.\CountLog\';
    sChrLogDir: '.\ChrLog\';
    boTestServer: true;
    boEnableMakingID: true;
    boGetbackPassword: true;
    boDynamicIPMode: False;
    boAutoClear: False;
    dwAutoClearTime: 3000;
    nReadyServers: 0;
    boAllowChangePassword: true;
    boShowDetailMsg: False;
    dwAddNewUserTick: 5000;
    dwChgPassWordTick: 5000;
    dwUpdateUserInfoTick: 5000;
    GetBackPasswordTick: 5000;
    nLockIdTick: 60 * 1000;
    CLPort: 3009;
    CLPwd: 12345;
    CLOpen: False;
    );

  FilterIPList              : TStringList;
  ReviceMsgList             : TList;
  StringList_0              : TStringList;
  nOnlineCountMin           : Integer;
  nOnlineCountMax           : Integer;
  //nMemoHeigh                : Integer;
  g_OutMessageCS            : TRTLCriticalSection;
  g_MainMsgList             : TStringList;
  CS_DB                     : TCriticalSection;
  n4753A4                   : Integer;
  n4753A8                   : Integer;
  n4753B0                   : Integer;
  n47328C                   : Integer;
  nSessionIdx               : Integer;

  bo470D20                  : Boolean;

  nVersionDate              : Integer = 20011006;

  ServerAddr                : array[0..99] of string[15];

  g_dwGameCenterHandle      : THandle;
  g_boCloseLoginGate        : Boolean = False;
  g_nCloseLoginGateTime     : Integer = 8;

  g_DataBaseType            : Byte = 1;{0=sqlite3 1=mariadb}

  g_RealmdServerAddress     : string = '127.0.0.1';
  g_RealmdServerPort        : Integer = 3306;
  g_RealmdAccount           : string = 'root';
  g_RealmdPassWord          : string = 'root';
  g_RealmdDataBase          : string = 'realmd';

  g_CharServerAddress       : string = '127.0.0.1';
  g_CharServerPort          : Integer = 3306;
  g_CharAccount             : string = 'root';
  g_CharPassWord            : string = 'root';
  g_CharDataBase            : string = 'characters';

  g_WorldServerAddress      : string = '127.0.0.1';
  g_WorldServerPort         : Integer = 3306;
  g_WorldAccount            : string = 'root';
  g_WorldPassWord           : string = 'root';
  g_WorldDataBase           : string = 'world';

implementation

function CheckAccountName(sName: string): Boolean;
var
  I                         : Integer;
  nLen                      : Integer;
begin
  Result := False;
  if sName = '' then
    Exit;
  Result := true;
  nLen := Length(sName);
  I := 1;
  while (true) do begin
    if I > nLen then Break;
    if (sName[I] < '0') or (sName[I] > 'z') then begin
      Result := False;
      if (sName[I] >= #$00B0) and (sName[I] <= #$00C8) then begin
        Inc(I);
        if I <= nLen then
          if (sName[I] >= #$00A1) and (sName[I] <= #$00FE) then
            Result := true;
      end;
      if not Result then
        Break;
    end;
    Inc(I);
  end;
end;

function GetSessionID(): Integer;
begin
  Inc(nSessionIdx);
  if nSessionIdx >= High(Integer) then
    nSessionIdx := 2;
  Result := nSessionIdx;
end;

procedure SaveGateConfig(Config: pTConfig);
var
  SaveList                  : TStringList;
  I, n8                     : Integer;
  s10, sC                   : string;
begin
  SaveList := TStringList.Create;
  SaveList.Add(';No space allowed');
  SaveList.Add(GenSpaceString(';Server', 15) + GenSpaceString('Title', 15) + GenSpaceString('Remote', 17) + GenSpaceString('Public', 17) + 'Gate...');
  for I := 0 to Config.nRouteCount - 1 do begin
    sC := GenSpaceString(Config.GateRoute[I].sServerName, 15) + GenSpaceString(Config.GateRoute[I].sTitle, 15) + GenSpaceString(Config.GateRoute[I].sRemoteAddr, 17) + GenSpaceString(Config.GateRoute[I].sPublicAddr, 17);
    n8 := 0;
    while (true) do begin
      s10 := Config.GateRoute[I].Gate[n8].sIPaddr;
      if s10 = '' then Break;
      if not Config.GateRoute[I].Gate[n8].boEnable then
        s10 := '*' + s10;
      s10 := s10 + ':' + IntToStr(Config.GateRoute[I].Gate[n8].nPort);
      sC := sC + GenSpaceString(s10, 17);
      Inc(n8);
      if n8 >= 10 then Break;
    end;
    SaveList.Add(sC);
  end;
  SaveList.SaveToFile('.\!addrtable.txt');
  SaveList.Free;
end;

function GetGatePublicAddr(Config: pTConfig; sGateIP: string): string;
var
  I                         : Integer;
begin
  Result := sGateIP;
  for I := 0 to Config.nRouteCount - 1 do begin
    if Config.GateRoute[I].sRemoteAddr = sGateIP then begin
      Result := Config.GateRoute[I].sPublicAddr;
      Break;
    end;
  end;
end;

function GenSpaceString(sStr: string; nSpaceCOunt: Integer): string;
var
  I                         : Integer;
begin
  Result := sStr + ' ';
  for I := 1 to nSpaceCOunt - Length(sStr) do begin
    Result := Result + ' ';
  end;
end;

procedure SendGameCenterMsg(wIdent: Word; sSendMsg: string);
var
  SendData                  : TCopyDataStruct;
  nParam                    : NativeUInt;
begin
  nParam := MakeLong(Word(tLoginSrv), wIdent);
  SendData.cbData := Length(AnsiString(sSendMsg)) + 1;
  GetMem(SendData.lpData, SendData.cbData);
  Move(PAnsiChar(AnsiString(sSendMsg))^, PAnsiChar(AnsiString(SendData.lpData))^, Length(AnsiString(sSendMsg)) + 1);
  SendMessage(g_dwGameCenterHandle, WM_COPYDATA, nParam, NativeUInt(@SendData));
  FreeMem(SendData.lpData);
end;

procedure MainOutMessage(sMsg: string);
begin
  EnterCriticalSection(g_OutMessageCS);
  try
    g_MainMsgList.Add(sMsg)
  finally
    LeaveCriticalSection(g_OutMessageCS);
  end;
end;

initialization
  ReviceMsgList := TList.Create;
  InitializeCriticalSection(g_OutMessageCS);
  g_MainMsgList := TStringList.Create;

finalization
  g_MainMsgList.Free;
  DeleteCriticalSection(g_OutMessageCS);
  ReviceMsgList.Free;

end.

